package com.mzj.saas.mservice.department.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.mzj.saas.commons.*;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.mservice.department.entity.*;
import com.mzj.saas.mservice.department.repository.*;
import com.mzj.saas.mservice.department.vo.CustomFieldValueVO;
import com.mzj.saas.mservice.department.vo.DepartmentParentVO;
import com.mzj.saas.mservice.department.vo.DepartmentVO;
import com.mzj.saas.mservice.department.vo.PeopleChangeDepartmentVO;
import com.mzj.saas.mservice.eligible.entity.DepartmentHierarchy;
import com.mzj.saas.mservice.eligible.repository.DepartmentHierarchyRepository;
import com.mzj.saas.mservice.lock.Repository.SmartLockAuthRepository;
import com.mzj.saas.mservice.lock.entity.SmartLockAuth;
import com.mzj.saas.mservice.property.entity.CommunityHouseUser;
import com.mzj.saas.mservice.property.repository.CommunityHouseUserRepository;
import com.mzj.saas.mservice.roles.entity.Role;
import com.mzj.saas.mservice.roles.entity.UserRoleRef;
import com.mzj.saas.mservice.roles.repository.RoleRepository;
import com.mzj.saas.mservice.roles.repository.UserRoleRefRepository;
import com.mzj.saas.mservice.roles.vo.UserRoleRefVO;
import com.mzj.saas.mservice.sys.entity.AppUser;
import com.mzj.saas.mservice.sys.entity.AppUserBackup;
import com.mzj.saas.mservice.sys.entity.User;
import com.mzj.saas.mservice.sys.repository.AppUserBackupRepository;
import com.mzj.saas.mservice.sys.repository.AppUserRepository;
import com.mzj.saas.mservice.sys.repository.UserRepository;
import com.mzj.saas.mservice.sys.utils.SqlUtils;
import com.mzj.saas.mservice.sys.vo.AppUserVO;
import com.mzj.saas.mservice.sys.vo.ParamVO;
import com.mzj.saas.mservice.sys.vo.UserVO;
import com.mzj.saas.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
public class DepartmentService {
    private static final Logger LOG = LoggerFactory.getLogger(DepartmentService.class);
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private RedisService redisService;
    @Autowired
    private DepartmentRepository departmentRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private UserDepartmentRefRepository userDepartmentRefRepository;
    @Autowired
    private UserRoleRefRepository userRoleRefRepository;
    @Autowired
    private CustomFieldManagementRepository customFieldManagementRepository;
    @Autowired
    private CustomFieldValueRepository customFieldValueRepository;
    @Autowired
    private FieldManagementRepository fieldManagementRepository;
    @Autowired
    private FieldStatusRefRepository fieldStatusRefRepository;
    @Autowired
    private DepartmentHierarchyRepository departmentHierarchyRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private AppUserRepository appUserRepository;
    @Autowired
    private AppUserBackupRepository appUserBackupRepository;
    @Autowired
    @Qualifier("stringRedisTemplate")
    public StringRedisTemplate redisTemplate;
    @Autowired
    private SmartLockAuthRepository smartLockAuthRepository;
    @Autowired
    private CommunityHouseUserRepository communityHouseUserRepository;

    /*
     * 获取当前用户拥有权限的组织架构
     */
    public ResultBean<Object> findUserDepartmentList(String accessToken, String depName) {
        LOG.info("DepartmentService findUserDepartmentList accessToken={},depName={}", accessToken, depName);
        ResultBean<Object> resultBean = new ResultBean<>();
        resultBean.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        resultBean.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        resultBean.setResultData(Collections.emptyList());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                resultBean.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                resultBean.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return resultBean;
            }

            User user = userRepository.findById(tokenRedisVo.getId());
            if (user == null) {
                return ResultBean.failedResultWithMsg("用户不存在或已删除");
            }

            List<Long> allDepIds = new ArrayList<>();
            List<DepartmentParentVO> dpList = null;
            if (tokenRedisVo.getMasterStatus() == 1) {
                dpList = findHierarchyParentAll(tokenRedisVo.getEnterpriseId());
                List<Long> ids = dpList.stream().map(d -> d.getOrgId()).collect(Collectors.toList());
                allDepIds.addAll(ids);
            } else {
                List<UserDepartmentRef> userDepartmentRefList = userDepartmentRefRepository.findByUserId(user.getId());
                for (UserDepartmentRef userDepartmentRef : userDepartmentRefList) {
                    allDepIds.add(userDepartmentRef.getDepId());
                }
            }

            List<Department> department = departmentRepository.findByIdIn(allDepIds);
            if (department == null || department != null && department.size() <= 0) {
                return ResultBean.failedResultWithMsg("部门不存在或已删除");
            }

            // 所有权限部门及其子集部门id
            List<Long> depIds = new ArrayList<>();
            depIds.addAll(allDepIds);
            for (Long depId : allDepIds) {
                depIds.addAll(allChild(depId));
            }
            depIds = depIds.stream().distinct().collect(Collectors.toList());

            List<Department> departmentList = new ArrayList<>();
            if (!StringUtils.isBlank(depName)) {
                departmentList = departmentRepository.findByIdInAndNameLikeOrderBySortbyDesc(depIds,
                        "%" + depName + "%");
            } else {
                departmentList = departmentRepository.findByIdInOrderByLevel(depIds);
            }

            List<Long> allChild = allChild(tokenRedisVo.getEnterpriseId());

            List<DepartmentVO> departmentVOList = new ArrayList<>();
            departmentList.forEach(dpm -> {
                DepartmentVO departmentVO = new DepartmentVO();
                BeanUtils.copyProperties(dpm, departmentVO);
                departmentVOList.add(departmentVO);
            });

            for (DepartmentVO d : departmentVOList) {
                if (tokenRedisVo.getEnterpriseId().equals(d.getId())) {
                    d.setCurrentCompany(1); // currentCompany: 1 当前企业 ,0 不是当前企业
                } else {
                    d.setCurrentCompany(0);
                }

                // 如果是当前企业的下级部门,也设置为1
                for (Long child : allChild) {
                    if (child.equals(d.getId())) {
                        d.setCurrentCompany(1);
                    }
                }

                // 层级架构，设置上下级关系
                if (dpList != null) {
                    for (DepartmentParentVO dParentVO : dpList) {
                        if (dParentVO.getOrgId().longValue() == d.getId().longValue() && dParentVO.getParentId() != null) {
                            d.setParentId(dParentVO.getParentId());
                        }
                    }
                }
            }

            LinkedList<Map<String, Object>> menuList = new LinkedList<Map<String, Object>>();
            findChild1(menuList, departmentVOList);

            resultBean.setResultData(menuList);
        } catch (Exception e) {
            resultBean.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            resultBean.setMsg(e.getMessage());
        }
        return resultBean;
    }

    /**
     * 获取未开门信息推送信息
     *
     * @param accessToken token
     * @return
     */
    public ResultBean<Department> getOpenPushInfo(String accessToken) {
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        Long enterpriseId = tokenRedisVo.getEnterpriseId();
        Optional<Department> byId = departmentRepository.findById(enterpriseId);
        return ResultBean.successfulResult(byId.get());
    }

    /**
     * 编辑未开门信息推送信息
     *
     * @param department
     * @return
     */
    public ResultBean<Object> updateOpenPushInfo(String accessToken, Department department) {
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        Optional<Department> byId = departmentRepository.findById(department.getId());
        if (byId.isPresent()) {
            Department update = byId.get();
            if (!tokenRedisVo.getEnterpriseId().equals(update.getId())) {
                return ResultBean.failedResultWithMsg("组织的操作数据异常");
            }
            update.setOpenPushMessageType(department.getOpenPushMessageType());
            update.setOpenPushMessageDay(department.getOpenPushMessageDay());
            departmentRepository.save(update);
            return ResultBean.successfulResult("");
        }
        return ResultBean.failedResultWithMsg("组织数据异常");
    }

    class OrgSort implements Comparator<Map<String, Object>> {

        @Override
        public int compare(Map<String, Object> e1, Map<String, Object> e2) {
            Integer type1 = Integer.parseInt(e1.get("currentCompany").toString());
            Integer type2 = Integer.parseInt(e2.get("currentCompany").toString());

            Object child1 = e1.get("child");
            Object child2 = e2.get("child");
            if ((type1 == 0 && type2 == 1) || (child1 != null && child2 == null)) {
                return 1;
            } else {
                return -1;
            }
        }
    }

    /*
     * 查询当前部门所在公司层级架构
     */
    public ResultBean<Object> findUserPresentDepartmentList(String accessToken) {
        LOG.info("DepartmentService findUserPresentDepartmentList accessToken={}", accessToken);
        ResultBean<Object> resultBean = new ResultBean<>();
        resultBean.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        resultBean.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        resultBean.setResultData(Collections.emptyList());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                resultBean.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                resultBean.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return resultBean;
            }
            User user = userRepository.findById(tokenRedisVo.getId());
            if (user == null) {
                return ResultBean.failedResultWithMsg("用户不存在或已删除");
            }
            List<Long> allDepIds = new ArrayList<>();
            allDepIds.add(tokenRedisVo.getEnterpriseId());
            if (tokenRedisVo.getMasterStatus() == 1) {
                allDepIds.addAll(allChild(tokenRedisVo.getEnterpriseId()));
            } else {
                List<UserDepartmentRef> userDepartmentRefList = userDepartmentRefRepository.findByUserId(user.getId());
                for (UserDepartmentRef userDepartmentRef : userDepartmentRefList) {
                    allDepIds.add(userDepartmentRef.getDepId());
                }
            }
            List<Department> department = departmentRepository.findByIdIn(allDepIds);
            if (department == null || department != null && department.size() <= 0) {
                return ResultBean.failedResultWithMsg("部门不存在或已删除");
            }
            // 所有权限部门及其子集部门id
            List<Long> depIds = new ArrayList<>();
            depIds.addAll(allDepIds);
            for (Long depId : allDepIds) {
                depIds.addAll(allChild(depId));
            }
            depIds = depIds.stream().distinct().collect(Collectors.toList());
            // 获取当前企业下所有部门和企业Id
            List<Long> companyIds = new ArrayList<>();
            companyIds.add(tokenRedisVo.getEnterpriseId());
            companyIds.addAll(allChild(tokenRedisVo.getEnterpriseId()));
            // 过滤其他企业权限(保留当前企业权限部门)
            if (depIds != null & depIds.size() != 0) {
                depIds = depIds.stream().filter((Long s) -> companyIds.contains(s)).collect(Collectors.toList());
            }
            List<Department> departmentList = departmentRepository.findByIdInOrderByLevel(depIds);
            List<Map<String, Object>> menuList = new LinkedList<Map<String, Object>>();
            findChild(menuList, departmentList);
            resultBean.setResultData(menuList);
        } catch (Exception e) {
            resultBean.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            resultBean.setMsg(e.getMessage());
        }
        return resultBean;
    }

    private void findChild(List<Map<String, Object>> menuList, List<Department> list) {
        for (Department vo : list) {
            if (hasParent(vo.getParentId(), list)) {
                continue;
            }
            Map<String, Object> firstMap = new LinkedHashMap<String, Object>();
            firstMap.put("id", vo.getId());
            firstMap.put("parentId", vo.getParentId());
            firstMap.put("name", vo.getName());
            firstMap.put("code", vo.getCode());
            firstMap.put("icon", vo.getIcon());
            firstMap.put("status", vo.getStatus());
            firstMap.put("maxNum", vo.getMaxNum());
            firstMap.put("sortBy", vo.getSortby());
            firstMap.put("num", findDepartmentPeopleNum(vo.getId(), vo.getParentId()));
            menuList.add(firstMap);
            findChildMenus(firstMap, vo, list);
        }
    }

    private void findChild1(List<Map<String, Object>> menuList, List<DepartmentVO> list) {
        for (DepartmentVO vo : list) {
            if (hasParent1(vo.getParentId(), list)) {
                continue;
            }
            Map<String, Object> firstMap = new LinkedHashMap<String, Object>();
            firstMap.put("id", vo.getId());
            firstMap.put("parentId", vo.getParentId());
            firstMap.put("name", vo.getName());
            firstMap.put("code", vo.getCode());
            firstMap.put("icon", vo.getIcon());
            firstMap.put("status", vo.getStatus());
            firstMap.put("maxNum", vo.getMaxNum());
            firstMap.put("sortBy", vo.getSortby());
            firstMap.put("num", findDepartmentPeopleNum(vo.getId(), vo.getParentId()));
            firstMap.put("currentCompany", vo.getCurrentCompany());

            menuList.add(firstMap);
            findChildMenus(firstMap, vo, list);
        }
    }

    /**
     * 查询层级架构下级orgId(包含当前orgId)
     *
     * @param orgId
     * @return
     */
    public List<Long> findHierarchyAll(Long orgId) {
        List<Long> orgIds = new ArrayList<>();
        orgIds.add(orgId);
        DepartmentHierarchy departmentHierarchy = departmentHierarchyRepository.findByOrgId(orgId);
        String sql = " SELECT org_id FROM ( SELECT t1.id,t1.org_id,IF(FIND_IN_SET(parent_id, @pids) > 0,@pids := CONCAT(@pids, ',', id),0) AS ischild FROM ( SELECT id,org_id,parent_id FROM `saas_department_hierarchy` t ORDER BY parent_id, id ) t1,(SELECT @pids := ?) t2 ) t3 WHERE ischild != 0 ";
        orgIds.addAll(jdbcTemplate.queryForList(sql, new Object[]{departmentHierarchy.getId()}, Long.class));
        return orgIds;
    }

    /*
     * 查询部门人数
     */
    public Integer findDepartmentPeopleNum(Long depId, Long parentId) {
        List<Long> idsList = new ArrayList<>();
        idsList.add(depId);
        if (parentId == 0) {
            idsList.addAll(allChild(depId));
        }
        StringBuffer ids = new StringBuffer();
        for (Long id : idsList) {
            ids.append(id).append(",");
        }
        String depIds = ids.substring(0, ids.lastIndexOf(","));
        String num = "SELECT COUNT(0) FROM `saas_user_department_ref` d INNER JOIN `saas_user` u ON u.id=d.user_id WHERE u.status != 2 \n";
        if (StringUtils.isNotBlank(depIds)) {
            num += "  AND d.dep_id IN (" + depIds + ")";
        }
        Integer count = jdbcTemplate.queryForObject(num, Integer.class);
        return count;
    }

    /*
     * 查找子类
     */
    private void findChildMenus(Map<String, Object> firstMap, Department parentVo, List<Department> list) {
        if (!hasChildren(parentVo.getId(), list)) {
            return;
        }
        List<Map<String, Object>> childList = new LinkedList<Map<String, Object>>();
        for (Department vo : list) {
            if (parentVo.getId().longValue() != vo.getParentId().longValue()) {
                continue;
            }
            Map<String, Object> childMap = new LinkedHashMap<String, Object>();
            childMap.put("id", vo.getId());
            childMap.put("parentId", vo.getParentId());
            childMap.put("name", vo.getName());
            childMap.put("code", vo.getCode());
            childMap.put("icon", vo.getIcon());
            childMap.put("status", vo.getStatus());
            childMap.put("maxNum", vo.getMaxNum());
            childMap.put("sortBy", vo.getSortby());
            childMap.put("num", findDepartmentPeopleNum(vo.getId(), vo.getParentId()));
            childList.add(childMap);
            Collections.sort(childList, new Comparator<Map<String, Object>>() {
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    return (Integer) o1.get("sortBy") < (Integer) o2.get("sortBy") ? 1
                            : ((Integer) o1.get("sortBy") == (Integer) o2.get("sortBy") ? 0 : -1);
                }
            });
            firstMap.put("child", childList);
            if (hasChildren(parentVo.getId(), list)) {
                findChildMenus(childMap, vo, list);
            }
        }
    }

    /*
     * 查找子类
     */
    private void findChildMenus(Map<String, Object> firstMap, DepartmentVO parentVo, List<DepartmentVO> list) {
        if (!hasChildren1(parentVo.getId(), list)) {
            return;
        }
        List<Map<String, Object>> childList = new LinkedList<Map<String, Object>>();
        for (DepartmentVO vo : list) {
            if (parentVo.getId().longValue() != vo.getParentId().longValue()) {
                continue;
            }
            Map<String, Object> childMap = new LinkedHashMap<String, Object>();
            childMap.put("id", vo.getId());
            childMap.put("parentId", vo.getParentId());
            childMap.put("name", vo.getName());
            childMap.put("code", vo.getCode());
            childMap.put("icon", vo.getIcon());
            childMap.put("status", vo.getStatus());
            childMap.put("maxNum", vo.getMaxNum());
            childMap.put("sortBy", vo.getSortby());
            childMap.put("num", findDepartmentPeopleNum(vo.getId(), vo.getParentId()));
            childMap.put("currentCompany", vo.getCurrentCompany());

            childList.add(childMap);
            Collections.sort(childList, new Comparator<Map<String, Object>>() {
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    return (Integer) o1.get("sortBy") < (Integer) o2.get("sortBy") ? 1
                            : ((Integer) o1.get("sortBy") == (Integer) o2.get("sortBy") ? 0 : -1);
                }
            });
            firstMap.put("child", childList);
            if (hasChildren1(parentVo.getId(), list)) {
                findChildMenus(childMap, vo, list);
            }

        }
        Collections.sort(childList, new OrgSort());
    }

    /*
     * 判断是否有父级
     */
    private boolean hasParent(Long id, List<Department> list) {
        for (Department vo : list) {
            if (id.longValue() != vo.getId().longValue()) {
                continue;
            }
            return true;
        }
        return false;
    }

    /*
     * 判断是否有父级
     */
    private boolean hasParent1(Long id, List<DepartmentVO> list) {
        for (DepartmentVO vo : list) {
            if (id.longValue() != vo.getId().longValue()) {
                continue;
            }
            return true;
        }
        return false;
    }

    /*
     * 判断是否有子集
     */
    private boolean hasChildren(Long id, List<Department> list) {
        for (Department vo : list) {
            if (id.longValue() != vo.getParentId().longValue()) {
                continue;
            }
            return true;
        }
        return false;
    }

    /*
     * 判断是否有子集
     */
    private boolean hasChildren1(Long id, List<DepartmentVO> list) {
        for (DepartmentVO vo : list) {
            if (id.longValue() != vo.getParentId().longValue()) {
                continue;
            }
            return true;
        }
        return false;
    }

    /*
     * 查找当前部门节点所有节点(不包含当前节点)
     */
    public List<Long> allChild(Long depId) {
        String sql = " select id from ( select t1.id,if(find_in_set(parent_id, @pids) > 0,@pids := concat(@pids, ',', id),0) as ischild from ( select id,parent_id from `saas_department` t order by parent_id, id ) t1,(select @pids := ?) t2 ) t3 where ischild != 0 \n";
        return jdbcTemplate.queryForList(sql, new Object[]{depId}, Long.class);
    }

    /*
     * 新增部门成员或修改人员信息
     */
    public ResultBean<Object> addDepartmentPeople(String accessToken, Map<String, Object> map) {
        LOG.info("DepartmentService addDepartmentPeople accessToken={},map={}", accessToken, map);
        ResultBean<Object> resultBean = new ResultBean<>();
        resultBean.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        resultBean.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        resultBean.setResultData(Collections.emptyList());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                resultBean.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                resultBean.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return resultBean;
            }

            if (map == null) {
                resultBean.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                resultBean.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                return resultBean;
            }

            Map<Long, Object> fieldList = new HashMap<>();
            UserVO userVO = new UserVO();
            UserRoleRefVO userRoleRefVO = new UserRoleRefVO();
            List<Integer> roles = new ArrayList<>();
            List<Integer> depIds = new ArrayList<>();
            if (map.get("id") == null) {
                User existUser = userRepository.findByMobile(map.get("mobile").toString());
                if (existUser != null) {
                    return ResultBean.failedResultWithMsg("当前手机号已被绑定");
                }
                userVO.setId("S" + KeyWorker.nextId());
                userVO.setCreateTime(new Date());
                userVO.setEntryTime(new Date());
                userVO.setType((short) 0);
                userVO.setPasswordStatus(1);
            } else {
                User user = userRepository.findById(String.valueOf(map.get("id")));
                BeanUtils.copyProperties(user, userVO);
                String id = (String) map.get("id");
                List<AppUser> byEnterpriseUserId = appUserRepository.findByEnterpriseUserId(id);
                if (ObjectUtil.isNotEmpty(byEnterpriseUserId)) {
                    String userId = byEnterpriseUserId.get(0).getId();
                    // 新增修改手机号后，修改智能锁用户列表手机号
                    List<SmartLockAuth> byAuthorUserId = smartLockAuthRepository.findByAuthorUserId(userId);
                    // if (ObjectUtil.isNotEmpty(byAuthorUserId)) {
                    //    byAuthorUserId.setMobile((String) map.get("mobile"));
                    //    smartLockAuthRepository.save(byAuthorUserId);
                    //}
                    if (CollectionUtil.isNotEmpty(byAuthorUserId)) {
                        for (SmartLockAuth smartLockAuth : byAuthorUserId) {
                            if (ObjectUtil.isNotEmpty(smartLockAuth)) {
                                smartLockAuth.setMobile((String) map.get("mobile"));
                                smartLockAuthRepository.save(smartLockAuth);
                            }
                        }
                    }
                    // 新增修改手机号后，修改成员登录用户列表手机号
                    List<CommunityHouseUser> byUserIdAndStatus = communityHouseUserRepository.findByUserIdAndStatus(userId, 1);
                    if (ObjectUtil.isNotEmpty(byUserIdAndStatus)) {
                        for (CommunityHouseUser userIdAndStatus : byUserIdAndStatus) {
                            CommunityHouseUser communityHouseUser = new CommunityHouseUser();
                            BeanUtils.copyProperties(userIdAndStatus, communityHouseUser);
                            communityHouseUser.setMobile((String) map.get("mobile"));
                            communityHouseUserRepository.save(communityHouseUser);
                        }
                    }
                }
            }

            Map<String, String> messageMap = new HashMap<>();
            Set<String> keySet = map.keySet();
            for (String key : keySet) {
                if ("name".equals(key) && map.get(key) != null) {
                    String name = String.valueOf(map.get(key));
                    userVO.setName(name);
                }
                if ("mobile".equals(key) && map.get(key) != null) {
                    String mobile = String.valueOf(map.get(key));
                    userVO.setMobile(mobile);
                }
                if ("depId".equals(key) && map.get(key) != null) {
                    depIds = (List<Integer>) map.get(key);
                }
                if ("roles".equals(key) && map.get(key) != null) {
                    roles = (List<Integer>) map.get(key);
                }
                if ("password".equals(key)) {
                    String password = null;
                    if (map.get(key) != null) {
                        password = String.valueOf(map.get(key));
                    } else {
                        password = redisService.getValue(Constant.REGISTER_DEFAULT_USER_PASSWORD);
                    }

                    if (StringUtils.isNotBlank(password)) {
                        byte[] salt = Digests.generateSalt(8);
                        String saltStr = Encodes.encodeHex(salt);
                        userVO.setSalt(saltStr);
                        byte[] hashPassword = Digests.sha1(password.getBytes(), salt, 1024);
                        String passwordMD5 = Encodes.encodeHex(hashPassword);
                        userVO.setPassword(passwordMD5);
                    }
                }
                if ("position".equals(key) && map.get(key) != null) {
                    String position = String.valueOf(map.get(key));
                    userVO.setPosition(position);
                }
                if ("email".equals(key) && map.get(key) != null) {
                    String email = String.valueOf(map.get(key));
                    userVO.setEmail(email);
                }
                if ("entryTime".equals(key) && map.get(key) != null) {
                    if (!StringUtils.isBlank(String.valueOf(map.get(key)))) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                        String date = String.valueOf(map.get(key));
                        userVO.setEntryTime(sdf.parse(date));
                    }
                }

                CustomFieldManagement existField = customFieldManagementRepository.findByFieldNameAndOrgId(key,
                        tokenRedisVo.getEnterpriseId());
                if (existField != null) {
                    fieldList.put(existField.getId(), map.get(key));
                    if (existField.getShowStatus() == 1 && existField.getMustStatus() == 1 && map.get(key) == null) {
                        messageMap.put(key, existField.getName() + "为必填选项");
                    }
                } else {
                    FieldManagement defaultFieldName = fieldManagementRepository.findByFieldName(key);
                    if (defaultFieldName != null) {
                        Long id = defaultFieldName.getId();
                        FieldStatusRef defaultFieldNameStatus = fieldStatusRefRepository
                                .findByOrgIdAndDefaultFieldId(tokenRedisVo.getEnterpriseId(), id);
                        if (defaultFieldNameStatus != null) {
                            Integer mustStatus = defaultFieldNameStatus.getMustStatus();
                            if (mustStatus == 1 && map.get(key) == null) {
                                messageMap.put(key, defaultFieldName.getName() + "为必填选项");
                            }
                        }
                    }
                }
            }

            if (depIds == null || depIds != null && depIds.size() == 0) {
                return ResultBean.failedResultWithMsg("部门不能为空");
            }
            if (messageMap != null && messageMap.size() != 0) {
                resultBean.setResultData(messageMap);
                return resultBean;
            }

            // 如果密码为空，设置为默认密码
            if (StringUtils.isEmpty(userVO.getPassword())) {
                String password = redisService.getValue(Constant.REGISTER_DEFAULT_USER_PASSWORD);
                if (StringUtils.isNotBlank(password)) {
                    byte[] salt = Digests.generateSalt(8);
                    String saltStr = Encodes.encodeHex(salt);
                    userVO.setSalt(saltStr);
                    byte[] hashPassword = Digests.sha1(password.getBytes(), salt, 1024);
                    String passwordMD5 = Encodes.encodeHex(hashPassword);
                    userVO.setPassword(passwordMD5);
                }
            }

            userVO.setStatus((short) 0);
            if (StringUtils.isNotBlank(userVO.getMobile())) {
                if (userVO.getMobile().length() > 11) {
                    return ResultBean.failedResultWithMsg("当前手机号格式不正确");
                }
                User existUser = userRepository.findByMobile(userVO.getMobile());
                if (existUser != null && !existUser.getId().equals(map.get("id"))) {
                    return ResultBean.failedResultWithMsg("当前手机号已被绑定");
                }
            }

            for (Integer depId : depIds) {
                Department department = departmentRepository.findById(Long.valueOf(depId)).get();
                List<UserDepartmentRef> departmentUser = userDepartmentRefRepository.findByDepId(Long.valueOf(depId));
                if (departmentUser != null) {
                    if (map.get("id") == null && department.getMaxNum() != null && departmentUser.size() >= department.getMaxNum()) {
                        return ResultBean.failedResultWithMsg("所添加的部门人数已达上限");
                    }
                }
            }

            User user = new User();
            BeanUtils.copyProperties(userVO, user);
            User save = userRepository.save(user);
            String id = save.getId();
            // 部门
            userDepartmentRefRepository.deleteAllByUserId(user.getId());
            for (Integer depId : depIds) {
                UserDepartmentRef userDepartmentRef = new UserDepartmentRef();
                userDepartmentRef.setUserId(save.getId());
                userDepartmentRef.setType(1);
                userDepartmentRef.setDepId(Long.valueOf(depId));
                userDepartmentRefRepository.save(userDepartmentRef);
            }
            // 角色
            userRoleRefRepository.deleteByUserId(id);
            userRoleRefVO.setUserId(id);
            for (Integer roleId : roles) {
                UserRoleRef userRoleRef = new UserRoleRef();
                userRoleRefVO.setRoleId(Long.valueOf(roleId));
                BeanUtils.copyProperties(userRoleRefVO, userRoleRef);
                Role role = roleRepository.findById(Long.valueOf(roleId)).get();
                UserRoleRef groupRef = new UserRoleRef();
                groupRef.setRoleId(role.getParentId());
                groupRef.setUserId(id);
                userRoleRefRepository.save(groupRef);
                userRoleRefRepository.save(userRoleRef);
            }

            Set<Long> longs = fieldList.keySet();
            for (Long key : longs) {
                CustomFieldValueVO customFieldValueVO = new CustomFieldValueVO();
                CustomFieldValue existCustomFieldValue = customFieldValueRepository.findByUserIdAndFieldId(id, key);
                if (existCustomFieldValue != null) {
                    customFieldValueVO.setId(existCustomFieldValue.getId());
                }
                customFieldValueVO.setFieldId(key);
                customFieldValueVO.setFieldValue(String.valueOf(fieldList.get(key)));
                customFieldValueVO.setUserId(id);
                CustomFieldValue customFieldValue = new CustomFieldValue();
                BeanUtils.copyProperties(customFieldValueVO, customFieldValue);
                customFieldValueRepository.save(customFieldValue);
            }

            // 查询登录用户信息
            AppUser loginUser = appUserRepository.findByPhone(userVO.getMobile());
            if (loginUser != null) {
                if (loginUser.getEnterpriseUserId() == null || loginUser.getEnterpriseUserId().equals("")) {
                    loginUser.setEnterpriseUserId(id);
                    loginUser.setType(1);
                    appUserRepository.save(loginUser);
                }

            }
            // 修复bug，把修改的user信息同步到APPuser表上
            AppUserVO appVO = new AppUserVO();
            // String mobile = user.getMobile();
            // AppUser byPhone = appUserRepository.findByPhone(mobile);
            AppUser byPhone;
            String appUserId = null;
            List<AppUser> byEnterpriseUserId = appUserRepository.findByEnterpriseUserId(id);
            for (AppUser appUser : byEnterpriseUserId) {
                appUserId = appUser.getId();
            }
            // Optional<AppUser> appUser = appUserRepository.findById(appUserId);
            if (byEnterpriseUserId.size() == 0) {
                appVO.setId("S" + KeyWorker.nextId());
                appVO.setEnterpriseUserId(user.getId());
                appVO.setName(user.getName());
                appVO.setSalt(user.getSalt());
                appVO.setPassword(user.getPassword());
                appVO.setPhone(user.getMobile());
                appVO.setStatus(1);
                appVO.setType(1);// 1.企业用户
                appVO.setRegistrationTime(user.getCreateTime());
                appVO.setCertificationStatus(0);// 默认未认证
            } else {
                // appUserRepository.deleteById(appUserId);
                // String userId = user.getId();
                // String appUserId = null;
                // List<AppUser> byEnterpriseUserId = appUserRepository.findByEnterpriseUserId(id);
                // for (AppUser appUser : byEnterpriseUserId) {
                //     appUserId = appUser.getId();
                // }
                // appUserRepository.deleteById(appUserId);
                appVO.setId(appUserId);
                appVO.setEnterpriseUserId(user.getId());
                appVO.setName(user.getName());
                appVO.setSalt(user.getSalt());
                appVO.setPassword(user.getPassword());
                appVO.setPhone(user.getMobile());
                appVO.setStatus(1);
                appVO.setType(1);// 1.企业用户
                appVO.setRegistrationTime(user.getCreateTime());
                appVO.setCertificationStatus(0);// 默认未认
            }
            byPhone = new AppUser();
            BeanUtils.copyProperties(appVO, byPhone);
            appUserRepository.save(byPhone);

        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            resultBean.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            resultBean.setMsg(StatusCode.ERROR_CODE_10001.getErrorMsg());
        }
        return resultBean;
    }

    /*
     * 显示部门子部门列表
     */
    public ResultBean<Object> presentDepartmentChild(String accessToken, Long id) {
        LOG.info("DepartmentService presentDepartmentChild accessToken={},id={}", accessToken, id);
        ResultBean<Object> result = new ResultBean<>();
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (id == null) {
                return ResultBean.failedResultWithMsg("部门id不能为空");
            }
            Optional<Department> existDepartment = departmentRepository.findById(id);
            if (existDepartment == null) {
                return ResultBean.failedResultWithMsg("部门信息不存在或是已删除");
            }
            String sql = " SELECT d.`id`,d.`parent_id`,d.`name`,a1.name AS provinceName,a2.name AS cityName,a3.name AS districtName,a4.name AS streetName,a5.`name` AS communityName FROM `saas_department` d "
                    + "LEFT JOIN `sys_area` a1 ON d.`province_id`=a1.id\n"
                    + "   LEFT JOIN `sys_area` a2 ON d.`city_id`=a2.id\n"
                    + "   LEFT JOIN `sys_area` a3 ON d.`district_id`=a3.id\n"
                    + "   LEFT JOIN `sys_area` a4 ON d.`street_id`=a4.id\n"
                    + "LEFT JOIN `sys_area` a5 ON d.`community_id`=a5.id"
                    + "   WHERE d.parent_id=? ORDER BY d.`sortby` DESC";
            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql, id);

            String userNumSQL = " select count(1) from saas_user_department_ref r inner join saas_user u on r.user_id=u.id where u.status !=2 and r.dep_id= ? ";

            for (Map<String, Object> map : mapList) {
                Long depId = (Long) map.get("id");
                Long userNum = jdbcTemplate.queryForObject(userNumSQL, Long.class, depId);
                map.put("userNum", userNum);
            }

            result.setResultData(mapList);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 显示部门成员
     */
    public ResultBean<Object> selectDepartmentPeople(String accessToken, Integer pageNumber, Integer pageSize,
                                                     Long depId, Integer sort) {
        LOG.info("---DepartmentService selectDepartmentPeople accessToken={},pageNumber={},pageSize={},depId={}",
                accessToken, pageNumber, pageSize, depId);
        ResultBean<Object> result = new ResultBean<>();
        ApiData<UserVO> apiData = new ApiData<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }

            if (tokenRedisVo.getEnterpriseId() == depId) {
                depId = tokenRedisVo.getEnterpriseId();
            }

            List<Long> idsList = allChild(depId);
            idsList.add(depId);
            String depIdSql = "SELECT `user_id` FROM `saas_user_department_ref` WHERE 1=1 ";
            StringBuffer depIds = new StringBuffer();
            for (Long id : idsList) {
                depIds.append(id).append(",");
            }
            String depIdSubstring = depIds.substring(0, depIds.lastIndexOf(","));
            if (depId != null) {
                depIdSql += "  AND `dep_id` IN (" + depIdSubstring + ")";
            }
            List<String> userIdsList = jdbcTemplate.queryForList(depIdSql, String.class);
            StringBuffer userIds = new StringBuffer();
            for (String s : userIdsList) {
                userIds.append("'").append(s).append("'").append(",");
            }

            String userId = StringUtils.isNotBlank(userIds) ? userIds.substring(0, userIds.lastIndexOf(",")) : null;
            String columns = "SELECT id,`name`,`mobile`,`email`,`password`,`salt`,`wrong_number`,`status`,`type`,`is_user_id`,`position`,`entry_time`,`remarks`,`job_number`,`create_time`,`leave_date`,`operator_id` FROM `saas_user` WHERE `status` != 2 \n";
            columns += "  AND `id` IN (" + userId + ")";
            String count = "SELECT COUNT(0) FROM (" + columns + ") c";
            String offsets = " LIMIT ? OFFSET ? ";
            List<Object> args = new ArrayList<>();

            // 查询总记录数
            Long total = jdbcTemplate.queryForObject(count, Long.class);
            if (total == 0) {
                result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
                result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
                result.setResultData(null);
                return result;
            }

            // 查询分页数据
            columns += offsets;
            args.add(pageSize);
            args.add(pageNumber * pageSize);
            List<UserVO> data = jdbcTemplate.query(columns, new BeanPropertyRowMapper<>(UserVO.class), args.toArray());

            String sql = "SELECT d.id,d.name,r.user_id AS userId FROM saas_user_department_ref r inner join saas_department d on r.dep_id=d.id  where r.user_id in ( "
                    + userId + ")";
            List<Map<String, Object>> departmentList = jdbcTemplate.queryForList(sql);

            data.forEach(d -> {
                departmentList.forEach(ref -> {
                    if (d.getId().equals(ref.get("userId"))) {
                        d.getDepIds().add((Long) ref.get("id"));
                        d.getDepNames().add((String) ref.get("name"));
                    }
                });

                List<UserRoleRef> userRoleRefs = userRoleRefRepository.findByUserId(d.getId());
                Integer mastUser = null;
                for (UserRoleRef userRoleRef : userRoleRefs) {
                    Role mastRole = roleRepository.findByIdAndOrgIdAndPropertyAndType(userRoleRef.getRoleId(),
                            tokenRedisVo.getEnterpriseId(), 2, 1);
                    if (mastRole != null) {
                        mastUser = mastRole.getType();
                    }
                }
                // 标识主管理管理员
                if (mastUser != null) {
                    d.setMastLogo(1);
                } else {
                    d.setMastLogo(0);
                }
            });

            if (sort != null) {
                if (sort.intValue() == 1) {
                    Collections.sort(data, (o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()));
                } else {
                    Collections.sort(data, (o1, o2) -> o1.getCreateTime().compareTo(o2.getCreateTime()));
                }
            }

            apiData.setData(data);
            apiData.setTotal(total);
            result.setResultData(apiData);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     *查询部门通信录下人员信息
     */
    public ResultBean<Object> selectServiceman(String accessToken, Long depId) {
        LOG.info("---DepartmentService selectDepartmentPeople accessToken={},depId={}",
                accessToken, depId);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (tokenRedisVo.getEnterpriseId() == depId) {
                depId = tokenRedisVo.getEnterpriseId();
            }
            List<Long> idsList = allChild(depId);
            idsList.add(depId);
            String depIdSql = "SELECT `user_id` FROM `saas_user_department_ref` WHERE 1=1 ";
            StringBuffer depIds = new StringBuffer();
            for (Long id : idsList) {
                depIds.append(id).append(",");
            }
            String depIdSubstring = depIds.substring(0, depIds.lastIndexOf(","));
            if (depId != null) {
                depIdSql += "  AND `dep_id` IN (" + depIdSubstring + ")";
            }
            List<String> userIdsList = jdbcTemplate.queryForList(depIdSql, String.class);
            StringBuffer userIds = new StringBuffer();
            for (String s : userIdsList) {
                userIds.append("'").append(s).append("'").append(",");
            }
            String userId = StringUtils.isNotBlank(userIds) ? userIds.substring(0, userIds.lastIndexOf(",")) : null;
            String columns = "SELECT id,`name`,`mobile`,`email`,`wrong_number`,`status`,`type`,`is_user_id`,`position`,`entry_time`,`remarks`,`job_number`,`create_time`,`leave_date`,`operator_id` FROM `saas_user` WHERE `status` != 2 \n";
            columns += "  AND `id` IN (" + userId + ")";
            List<Object> args = new ArrayList<>();
            List<UserVO> data = jdbcTemplate.query(columns, new BeanPropertyRowMapper<>(UserVO.class), args.toArray());
            result.setResultData(data);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 修改部门名称
     */
    public ResultBean<Object> updateDepartmentName(String accessToken, String name, Long depId) {
        LOG.info("---DepartmentService updateDepartmentName accessToken={},name={},depId={}", accessToken, name, depId);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (StringUtils.isBlank(name) || depId == null) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }
            result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
            result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
            Optional<Department> departmentOptional = departmentRepository.findById(depId);// 数据库查出待更新对象
            if (!departmentOptional.isPresent()) {
                return ResultBean.failedResultWithMsg("部门不存在或已删除");
            }
            Department department = departmentOptional.get();
            Long existDepartmentName = existDepartmentName(tokenRedisVo.getEnterpriseId(), name,
                    department.getParentId());
            if (existDepartmentName != null) {
                return ResultBean.failedResultWithMsg("名称已被使用");
            }
            department.setName(name);
            Department save = departmentRepository.save(department);
            if (department.getParentId() == 0 && tokenRedisVo.getEnterpriseId() == department.getId()) {
                DepartmentHierarchy departmentHierarchy = departmentHierarchyRepository.findByOrgId(department.getId());
                departmentHierarchy.setName(name);
                departmentHierarchy.setLastUpdateTime(new Date());
                departmentHierarchyRepository.save(departmentHierarchy);
            }
            result.setResultData(save);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 下级部门顺序调整
     */
    public ResultBean<Object> changeChildDepartmentSort(String accessToken, Long[] ids) {
        LOG.info("---DepartmentService changeChildDepartmentSort accessToken={},ids={}", accessToken, JSON.toJSONString(ids));
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (ids == null) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }
            int i = ids.length;
            for (Long id : ids) {
                Department department = departmentRepository.findById(id).get();
                if (department == null) {
                    return ResultBean.failedResultWithMsg("部门不存在或已删除");
                }
                department.setSortby(i--);
                departmentRepository.save(department);
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 部门人员调整部门
     */
    @Transactional
    public ResultBean<Object> userUpdateDepartment(String accessToken,
                                                   PeopleChangeDepartmentVO peopleChangeDepartmentVO) {
        LOG.info("---DepartmentService userUpdateDepartment accessToken={},peopleChangeDepartmentVO={}", accessToken,
                JSON.toJSONString(peopleChangeDepartmentVO));
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (peopleChangeDepartmentVO == null) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }
            if (peopleChangeDepartmentVO.getDepIds() == null || peopleChangeDepartmentVO.getUserIds() == null) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }
            List<Long> depIds = peopleChangeDepartmentVO.getDepIds();
            String[] userIds = peopleChangeDepartmentVO.getUserIds();
            if (userIds.length == 0) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }
            List<UserDepartmentRef> list = new ArrayList<>();
            for (String userId : userIds) {
                User user = userRepository.findById(userId);// 数据库查出待更新对象
                if (user != null) {
                    userDepartmentRefRepository.deleteAllByUserId(userId);
                    for (Long depId : depIds) {
                        Optional<Department> existDepartment = departmentRepository.findById(depId);
                        if (existDepartment != null) {
                            UserDepartmentRef userDepartmentRef = new UserDepartmentRef();
                            userDepartmentRef.setDepId(depId);
                            userDepartmentRef.setUserId(user.getId());
                            userDepartmentRef.setType(1);
                            list.add(userDepartmentRef);
                        }
                    }
                }
            }
            List<UserDepartmentRef> userDepartmentRefList = userDepartmentRefRepository.saveAll(list);
            if (userDepartmentRefList == null) {
                result.setMsg(StatusCode.ERROR_CODE_10001.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
                return result;
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 修改通道状态
     */
    public ResultBean<Object> updatePassStatus(String accessToken, Integer status, Long depId) {
        LOG.info("---DepartmentService updatePassStatus accessToken={},depId={},status={}", accessToken, depId, status);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (status == null || depId == null) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }
            result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
            result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
            Optional<Department> departmentOptional = departmentRepository.findById(depId);// 数据库查出待更新对象
            if (departmentOptional == null) {
                return ResultBean.failedResultWithMsg("部门不存在或已删除");
            }
            Department department = departmentOptional.get();
            department.setStatus(status);
            Department save = departmentRepository.save(department);
            result.setResultData(save);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 新增子部门
     */
    public ResultBean<Object> addChildDepartment(String accessToken, DepartmentVO departmentVO) {
        LOG.info("---DepartmentService addChildDepartment accessToken={},departmentVO={}", accessToken, JSON.toJSONString(departmentVO));
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (departmentVO == null && departmentVO.getParentId() == null) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }
            Department parentDepartment = departmentRepository.findById(departmentVO.getParentId()).get();
            if (parentDepartment == null) {
                result.setMsg(StatusCode.ERROR_CODE_10001.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
                return result;
            }
            Department department = departmentRepository.findById(departmentVO.getParentId()).get();
            Department child = new Department();
            // departmentVO.setCode(buildCode(departmentVO.getParentId(), tokenRedisVo.getEnterpriseId()));
            departmentVO.setStatus(0);
            departmentVO.setSortby(department.getSortby() + 1);
            departmentVO.setType(3);
            departmentVO.setCreateTime(new Date());
            departmentVO.setActivateStatus(1);
            Department existDepartment = departmentRepository.findAllByParentIdAndName(departmentVO.getParentId(),
                    departmentVO.getName());
            if (existDepartment != null) {
                return ResultBean.failedResultWithMsg("名称已被使用");
            }
            BeanUtils.copyProperties(departmentVO, child);
            departmentRepository.save(child);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 生成code
     */
    private String buildCode(Long parentId, Long companyId) {
        // 找同级Code
        boolean b = departmentRepository.existsByParentId(parentId);
        String str, parentCodeStr;
        int code;
        if (!b) {
            // 找父级Code
            Optional<Department> optionalById = departmentRepository.findById(parentId);
            if (!optionalById.isPresent()) {
                Optional<Department> company = departmentRepository.findById(companyId);
                parentCodeStr = company.get().getCode();
            } else {
                parentCodeStr = optionalById.get().getCode();
            }
            return parentCodeStr + "001";
        }
        Long maxId = departmentRepository.findByParentIdMaxId(parentId);
        Optional<Department> optionalByParentId = departmentRepository.findById(maxId);
        code = Integer.parseInt(optionalByParentId.get().getCode()) + 1;
        str = "000" + code;
        String codeStr = str.substring(str.length() - optionalByParentId.get().getCode().length());

        return codeStr;
    }

    /*
     * 批量删除部门成员
     */
    public ResultBean<Object> deleteDepartmentPeople(String accessToken, String[] userIds) {
        LOG.info("---DepartmentService deleteDepartmentPeople accessToken={},userIds={}", accessToken, JSON.toJSONString(userIds));
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (userIds == null) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }
            result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
            result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());

            // 判断标识
            Integer flag = 0;
            Integer login = 0;
            String mastName = "";

            for (String userId : userIds) {
                User user = userRepository.findById(userId);
                // 主管理员
                Role role = roleRepository.findByOrgIdAndType(tokenRedisVo.getEnterpriseId(), 1);
                List<UserRoleRef> userRoleRefList = userRoleRefRepository.findByRoleId(role.getId());
                UserRoleRef mastRoleUser = new UserRoleRef();
                if (userRoleRefList.size() > 0) {
                    mastRoleUser = userRoleRefList.get(0);
                }

                if (userId.equals(mastRoleUser.getUserId())) {
                    mastName = user.getName();
                    flag = 2;
                } else {
                    if (user != null && !tokenRedisVo.getId().equals(userId)) {
                        Short status = 2;
                        user.setStatus(status);
                        user.setLeaveDate(new Date());
                        user.setOperatorId(tokenRedisVo.getId());
                        userRepository.save(user);
                        userRoleRefRepository.deleteByUserId(user.getId());
                        // userDepartmentRefRepository.deleteAllByUserId(user.getId());

                        // 同步AppUser
                        List<AppUser> appUserList = appUserRepository.findByEnterpriseUserId(userId);
                        for (AppUser appUser : appUserList) {
                            // status 状态：0禁用 1启用 2已删除
                            appUser.setStatus(2);
                            appUserRepository.deleteById(appUser.getId());

                            Object object1 = redisTemplate.opsForValue().get(Constant.LOGIN_USER + ":" + appUser.getEnterpriseUserId() + ":1");
                            Object object2 = redisTemplate.opsForValue().get(Constant.LOGIN_USER + ":" + appUser.getEnterpriseUserId() + ":2");
                            if (object1 != null) {
                                redisTemplate.delete((String) object1);
                            }
                            if (object2 != null) {
                                redisTemplate.delete((String) object2);
                            }

                            AppUserBackup appUserBackup = new AppUserBackup();
                            BeanUtils.copyProperties(appUser, appUserBackup);
                            appUserBackupRepository.save(appUserBackup);
                        }
                    } else {
                        login = 1;
                    }
                }
            }

            if (flag == 2) {
                return ResultBean.failedResultWithMsg(mastName + "是主管理员不能删除，只能更换");
            }
            if (login == 1) {
                return ResultBean.failedResultWithMsg("用户正在使用中不能删除");
            }

        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 批量导入
     */
    @Transactional
    public ResultBean<Object> excelInputdate(String accessToken, Long depId, MultipartFile mfile) {
        LOG.info("---DepartmentService excelInputdate accessToken={},depId={},mfile={}", accessToken, depId, mfile);
        List<Map<String, Object>> listob = null;
        List<UserVO> list = new ArrayList<>();
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            InputStream in = null;
            if (mfile.isEmpty()) {
                throw new Exception("文件不存在！");
            }
            in = mfile.getInputStream();
            listob = new ImportExcelUtil().getBankListByExcel(in, mfile.getOriginalFilename());
        } catch (Exception e) {
            result.setMsg(StatusCode.ERROR_CODE_10001.getErrorMsg());
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            LOG.error(e.getMessage(), e);
        }

        Date date = new Date();
        Integer success = 0;
        List<Map<String, Object>> maps = getCompanyField(tokenRedisVo.getEnterpriseId());
        Map<String, Integer> showFieldNameMap = new HashMap<>();
        for (Map<String, Object> map : maps) {
            Integer mustStatus = Integer.valueOf(String.valueOf(map.get("mustStatus")));
            showFieldNameMap.put(String.valueOf(map.get("fieldName")), mustStatus);
        }
        if (listob != null && listob.size() > 0) {
            // 设置锚点
            boolean end = true;
            for (int i = 0; i < listob.size(); i++) {
                Map<String, Object> map = listob.get(i);
                if (map != null && map.size() > 0 && !map.isEmpty()) {
                    Map<String, Object> customFieldList = new HashMap<>();
                    UserVO userVO = new UserVO();
                    userVO.setId("S" + KeyWorker.nextId());
                    userVO.setStatus((short) 0);
                    Set<String> strings = map.keySet();
                    if (i == 0) {
                        if (strings.size() != showFieldNameMap.size()) {
                            return ResultBean.failedResultWithMsg("模板已发生更改，请下载最新模板");
                        }
                    } else {
                        Set<String> showFieldKeys = showFieldNameMap.keySet();
                        for (String fieldName : showFieldKeys) {
                            if (showFieldNameMap.get(fieldName) == 1) {
                                if (!map.containsKey(fieldName)) {
                                    end = false;
                                    break;
                                } else {
                                    if (StringUtils.isBlank(String.valueOf(map.get(fieldName)))) {
                                        end = false;
                                        break;
                                    }
                                }
                            }
                        }
                        if (!end) {
                            continue;
                        }
                        for (String string : strings) {
                            if ("name".equals(string)) {
                                Object name = map.get("name");
                                if (name != null) {
                                    userVO.setName(String.valueOf(name));
                                }
                            } else if ("mobile".equals(string)) {
                                Object mobile = map.get("mobile");
                                if (mobile != null) {
                                    userVO.setMobile(String.valueOf(mobile));
                                }
                            } else if ("depId".equals(string)) {
                                Object depName = map.get("depId");
                                if (depName != null) {
                                    userVO.setDepName(String.valueOf(depName));
                                }
                            } else if ("position".equals(string)) {
                                Object position = map.get("position");
                                if (position != null) {
                                    userVO.setPosition(String.valueOf(position));
                                }
                            } else if ("email".equals(string)) {
                                Object email = map.get("email");
                                if (email != null) {
                                    userVO.setEmail(String.valueOf(email));
                                }
                            } else if ("entryTime".equals(string)) {
                                Object entryTime = map.get("entryTime");
                                if (entryTime != null) {
                                    userVO.setJoinTime(String.valueOf(entryTime));
                                }
                            } else if ("role".equals(string)) {
                                Object role = map.get("role");
                                if (role != null) {
                                    userVO.setRole(String.valueOf(role));
                                }
                            } else if ("password".equals(string)) {
                                String password = map.get("password").toString();
                                if (StringUtils.isNotBlank(password)) {
                                    byte[] salt = Digests.generateSalt(8);
                                    String saltStr = Encodes.encodeHex(salt);
                                    userVO.setSalt(saltStr);
                                    byte[] hashPassword = Digests.sha1(password.getBytes(), salt, 1024);
                                    String passwordMD5 = Encodes.encodeHex(hashPassword);
                                    userVO.setPassword(passwordMD5);
                                }
                            } else {
                                customFieldList.put(string, map.get(string));
                            }
                        }
                        userVO.setCustomFieldList(customFieldList);
                        userVO.setCreateTime(date);
                        list.add(userVO);
                    }
                }
            }
        } else {
            return ResultBean.failedResultWithMsg("导入失败，数据内容为空");
        }
        // 用户所有部门
        for (int i = 0; i < list.size(); i++) {
            List<Long> allDepIds = new ArrayList<>();
            UserVO userVO = list.get(i);
            if (StringUtils.isNotBlank(userVO.getMobile())) {
                if (userVO.getMobile().length() > 11) {
                    continue;
                }
                User existUser = userRepository.findByMobile(userVO.getMobile());
                if (existUser != null) {
                    continue;
                }
            }
            if (StringUtils.isBlank(userVO.getDepName())) {
                continue;
            }
            // 设置判断角色信息是否正确的锚点
            boolean b = true;
            String role = userVO.getRole();
            if (StringUtils.isNotBlank(role)) {
                String[] split = role.split(",");
                for (String s : split) {
                    Role roleInfo = roleRepository.findByOrgIdAndPropertyAndName(tokenRedisVo.getEnterpriseId(), 2, s);
                    if (roleInfo == null) {
                        return ResultBean.failedResultOfParamWithMsg(s + "该角色不存在");
                        // b = false;
                        // continue;
                    }
                }
            }
            if (!b) {
                continue;
            }
            if (StringUtils.isNotBlank(userVO.getJoinTime())) {
                try {
                    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
                    String joinTime = userVO.getJoinTime();
                    Date parse = sd.parse(joinTime);
                    userVO.setEntryTime(parse);
                } catch (Exception e) {
                    continue;
                }
            }
            if (StringUtils.isNotBlank(userVO.getDepName())) {
                String[] manyDepartment = userVO.getDepName().split(",");
                for (String deptNames : manyDepartment) {
                    List<Long> depIds = new ArrayList<>();
                    String[] split = deptNames.split("-");
                    for (int j = 0; j < split.length; j++) {
                        Long parentId = tokenRedisVo.getEnterpriseId();
                        if (j > 0 && deptNames.contains("-")) {
                            parentId = depIds.get(depIds.size() - 1);
                        }
                        Long existDepartmentId = existDepartmentName(tokenRedisVo.getEnterpriseId(), split[j],
                                parentId);
                        if (existDepartmentId != null) {
                            depIds.add(existDepartmentId);
                        } else {
                            // Department existDepartment = departmentRepository.findAllByParentIdAndName(departmentVO.getParentId(),
                            //         departmentVO.getName());
                            // if (existDepartment != null) {
                            //     return ResultBean.failedResultWithMsg("名称已被使用");
                            // }

                            Department department = departmentRepository.findByNameAndParentId(split[j], parentId);
                            if (ObjectUtil.isEmpty(department)) {
                                Department addDepartment = new Department();
                                addDepartment.setParentId(parentId);
                                addDepartment.setName(userVO.getDepName());
                                addDepartment.setType(3);
                                addDepartment.setActivateStatus(0);
                                addDepartment.setOwnerType(0);
                                addDepartment.setSortby(0);
                                addDepartment.setCreateTime(new Date());
                                department = departmentRepository.save(addDepartment);
                            }
                            if (department != null) {
                                depIds.add(department.getId());
                            }
                        }
                    }
                    allDepIds.addAll(depIds);
                }
                // 去重
                allDepIds = allDepIds.stream().distinct().collect(Collectors.toList());
            }
            if (b) {
                if (StringUtils.isNotBlank(role)) {
                    String[] split = role.split(",");
                    for (String s : split) {
                        Role roleInfo = roleRepository.findByOrgIdAndPropertyAndName(tokenRedisVo.getEnterpriseId(), 2,
                                s);
                        if (roleInfo != null) {
                            UserRoleRef userRoleRef = new UserRoleRef();
                            userRoleRef.setRoleId(roleInfo.getId());
                            userRoleRef.setUserId(userVO.getId());
                            UserRoleRef existUserRole = userRoleRefRepository
                                    .findByUserIdAndRoleId(userRoleRef.getUserId(), roleInfo.getId());
                            if (existUserRole == null) {
                                UserRoleRef save = userRoleRefRepository.save(userRoleRef);
                                if (save != null) {
                                    UserRoleRef existUserRoleGroup = userRoleRefRepository
                                            .findByUserIdAndRoleId(userRoleRef.getUserId(), roleInfo.getParentId());
                                    if (existUserRoleGroup == null) {
                                        UserRoleRef group = new UserRoleRef();
                                        group.setRoleId(roleInfo.getParentId());
                                        group.setUserId(userVO.getId());
                                        userRoleRefRepository.save(group);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            User user = new User();
            BeanUtils.copyProperties(userVO, user);
            User save = userRepository.save(user);
            if (save != null) {
                for (Long addDepId : allDepIds) {
                    UserDepartmentRef userDepartmentRef = new UserDepartmentRef();
                    userDepartmentRef.setType(1);
                    userDepartmentRef.setDepId(addDepId);
                    userDepartmentRef.setUserId(save.getId());
                    userDepartmentRefRepository.save(userDepartmentRef);
                }
                Map<String, Object> customFieldList = userVO.getCustomFieldList();
                Set<String> customFieldSet = customFieldList.keySet();
                for (String s : customFieldSet) {
                    CustomFieldManagement existField = customFieldManagementRepository.findByFieldNameAndOrgId(s,
                            tokenRedisVo.getEnterpriseId());
                    if (existField != null) {
                        CustomFieldValueVO customFieldValueVO = new CustomFieldValueVO();
                        CustomFieldValue existCustomFieldValue = customFieldValueRepository
                                .findByUserIdAndFieldId(userVO.getId(), existField.getId());
                        if (existCustomFieldValue != null) {
                            customFieldValueVO.setId(existCustomFieldValue.getId());
                        }
                        customFieldValueVO.setFieldId(existField.getId());
                        customFieldValueVO.setFieldValue(String.valueOf(customFieldList.get(s)));
                        customFieldValueVO.setUserId(userVO.getId());
                        CustomFieldValue customFieldValue = new CustomFieldValue();
                        BeanUtils.copyProperties(customFieldValueVO, customFieldValue);
                        customFieldValueRepository.save(customFieldValue);
                    }
                }
                success++;
            }
        }
        result.setResultData("导入成功:" + success + "条，失败:" + ((listob.size() - 1) - success) + "条");
        return result;
    }

    /*
     * 验证部门名称是否在当前企业中存在
     */
    public Long existDepartmentName(Long companyId, String name, Long parentId) {
        String sql = "  SELECT id FROM ( SELECT t1.id,IF(FIND_IN_SET(parent_id, @pids) > 0,@pids := CONCAT(@pids, ',', id),0) AS ischild,t1.`name`,t1.parent_id FROM ( SELECT id,parent_id,`name` FROM `saas_department` t ORDER BY parent_id, id ) t1,(SELECT @pids := ?) t2 ) t3 WHERE ischild != 0 AND `name`=?  AND parent_Id!= ? \n";
        Long aLong = null;
        try {
            aLong = jdbcTemplate.queryForObject(sql, new Object[]{companyId, name, parentId}, Long.class);
            if (aLong != null) {
                return aLong;
            }
        } catch (EmptyResultDataAccessException e) {
            aLong = null;
        }
        return aLong;
    }

    /**
     * excel的模板下载
     */
    public void excelDownLoad(String accessToken, HttpServletResponse response) {
        LOG.info("---DepartmentService excelDownLoad accessToken={}", accessToken);
        HSSFWorkbook workbook = null;
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                return;
            }
            Optional<Department> companyOptional = departmentRepository.findById(tokenRedisVo.getEnterpriseId());
            if (companyOptional == null) {
                return;
            }
            List<Map<String, Object>> maps = getCompanyField(tokenRedisVo.getEnterpriseId());
            workbook = new HSSFWorkbook();
            HSSFSheet sheet = workbook.createSheet("sheet1");
            HSSFRow headRow = sheet.createRow(0);
            ;
            headRow.setHeightInPoints(267);
            HSSFCell headCell = headRow.createCell(0);
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, maps.size() - 1));
            headCell.setCellValue(
                    "填写须知：\n" + " <1>不能在本excel表中对员工信息类别进行增加、删除、修改，若员工信息类别不足，请进入“企业管理后台-设置-通讯录信息设置”进行添加，完成后重新下载新模板；\n"
                            + " <2>红色字段为必填字段，黑色字段为选填字段；\n" + " <3>员工UserID：员工在企业的唯一标识，该字段可初始设定或自动生成，且不可修改；\n"
                            + " <4>部门：上下级部门间用‘-’隔开，且从最上级部门开始，例如“市场部-杭州分部”，多部门和多部门主管都用英文的“,”隔开；\n"
                            + " <5>手机号：如果是国内手机号，直接填写手机号即可，如果是国外手机号，需要添加国家码，例如+xx-xxxxxx；\n"
                            + " <6>入职时间：请按2017-04-21这样的格式填写，否则无法正常识别；\n"
                            + " <7>角色：请先到内部通讯录管理-角色先添加好，再到本excel里填入，多角色用英文的“,”隔开；");
            VerticalAlignment center = VerticalAlignment.CENTER;

            HSSFCellStyle style = workbook.createCellStyle(); // 样式对象
            style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 水平
            style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
            style.setWrapText(true);
            // 生成一个字体
            HSSFFont font = workbook.createFont();
            font.setColor(HSSFColor.BLACK.index);// 字体颜色
            font.setFontName("宋体");
            font.setFontHeightInPoints((short) 18);
            font.setBold(true);// 字体增粗
            // 把字体应用到当前的样式
            style.setFont(font);
            headCell.setCellStyle(style);
            HSSFCellStyle style2 = workbook.createCellStyle();
            style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直
            HSSFFont font2 = workbook.createFont();
            font2.setColor(HSSFColor.BLACK.index);// 字体颜色
            font2.setFontName("宋体");
            font2.setFontHeightInPoints((short) 12);
            style2.setFont(font2);
            HSSFRow row2 = sheet.createRow(1);
            row2.setHeightInPoints(25);
            HSSFCell cell = row2.createCell(0);
            sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, maps.size() - 1));
            cell.setCellValue(companyOptional.get().getName() + "-通讯录模板");
            cell.setCellStyle(style2);
            HSSFRow row3 = sheet.createRow(2);
            HSSFPatriarch p = sheet.createDrawingPatriarch();
            HSSFCellStyle style3 = workbook.createCellStyle();
            style3.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            style3.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直
            HSSFFont font3 = workbook.createFont();
            font3.setColor(HSSFColor.RED.index);// 字体颜色
            font3.setFontName("宋体");
            font3.setFontHeightInPoints((short) 12);
            style3.setFont(font3);

            for (int i = 0; i < maps.size(); i++) {
                Map<String, Object> map = maps.get(i);
                sheet.setColumnWidth(i, 252 * 15 + 323);
                HSSFCell cell1 = row3.createCell(i);
                cell1.setCellStyle(style2);
                // must_status '是否必填：0非必填 1必填',
                Integer mustStatus = (Integer) map.get("mustStatus");
                if (mustStatus != null) {
                    if (mustStatus.intValue() == 1) {
                        cell1.setCellStyle(style3);
                    }
                }
                cell1.setCellValue(String.valueOf(map.get("name")));
                HSSFComment comment = p.createComment(new HSSFClientAnchor(i, 2, i, 2, (short) 4, 4, (short) 6, 7));// 输入批注信息
                comment.setString(new HSSFRichTextString(String.valueOf(map.get("fieldName"))));// 添加作者,选中B5单元格,看状态栏
                comment.setAuthor("toad");// 将批注添加到单元格对象中
                cell1.setCellComment(comment);

            }
            String fileName = URLEncoder.encode("嗨小克通讯录模板.xls", "utf-8");
            FileOutputStream fos = new FileOutputStream(fileName);
            workbook.write(fos);
            fos.flush();
            fos.close();
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            OutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
        } finally {
            // 关闭
            try {
                if (workbook != null) {
                    workbook.close();
                }
            } catch (IOException e) {
                LOG.error(e.getMessage(), e);
            }
        }
    }

    /*
     * 获取企业通讯录定义字段
     */
    public List<Map<String, Object>> getCompanyField(Long companyId) {
        String sql = "(SELECT m.id,m.field_name AS fieldName,m.name,sa.show_status AS showStatus,sa.must_status AS mustStatus,0 AS TYPE FROM saas_field_management m INNER JOIN saas_field_stauts_ref sa  ON m.`id`=sa.`default_field_id` WHERE  sa.org_id = ? ) UNION ALL (SELECT fm.id,fm.field_name AS fieldName,fm.name,fm.show_status AS showStatus,fm.must_status AS mustStatus,1 AS TYPE FROM saas_custom_field_management fm  WHERE fm.`show_status`=1  AND  fm.org_id = ?)\n";
        return jdbcTemplate.queryForList(sql, new Object[]{companyId, companyId});
    }

    /*
     * 员工部门权限修改
     */
    public ResultBean<Object> changeDepartmentPeoplePermission(String accessToken, ParamVO paramVO) {
        LOG.info("---DepartmentService changeDepartmentPeoplePermission accessToken={},paramVO={}", accessToken,
                paramVO);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        try {
            if (paramVO == null) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }
            if (paramVO.getUserId() == null) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }
            if (paramVO.getLongIds() == null && paramVO.getLongIds().size() == 0) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }

            String userId = paramVO.getUserId();
            List<Long> ids = paramVO.getLongIds();
            User user = userRepository.findById(userId);
            if (user == null) {
                return ResultBean.failedResultWithMsg("用户不存在或已删除");
            }

            userDepartmentRefRepository.deleteAllByUserId(userId);
            for (Long id : ids) {
                Department department = departmentRepository.findById(id).get();
                if (department == null) {
                    return ResultBean.failedResultWithMsg("部门不存在或已删除");
                }
                UserDepartmentRef userDepartmentRef = new UserDepartmentRef();
                userDepartmentRef.setUserId(userId);
                userDepartmentRef.setDepId(id);
                userDepartmentRefRepository.save(userDepartmentRef);
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 根据用户拥有的权限部门
     */
    public ResultBean<Object> userPermissionDepartment(String accessToken, String userId) {
        LOG.info("---DepartmentService userPermissionDepartment accessToken={},userId={}", accessToken, userId);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (userId == null) {
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                return result;
            }
            String sql = "SELECT dep_id FROM saas_user_department_ref WHERE  user_id=?";
            List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, new Object[]{userId});
            List<Department> departmentList = new ArrayList<>();
            maps.forEach(m -> {
                Object dep_id = m.get("dep_id");
                if (dep_id != null) {
                    Long depId = (Long) dep_id;
                    Optional<Department> departmentOptional = departmentRepository.findById(depId);
                    if (departmentOptional != null) {
                        Department department = departmentOptional.get();
                        departmentList.add(department);
                    }
                }
            });
            result.setResultData(departmentList);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 显示当前企业设置的新增成员字段信息
     */
    public ResultBean<Object> addDepartmentFieldList(String accessToken) {
        LOG.info("---DepartmentService addDepartmentFieldList accessToken={}", accessToken);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            Optional<Department> existDepartment = departmentRepository.findById(tokenRedisVo.getEnterpriseId());
            if (existDepartment == null) {
                return ResultBean.failedResultWithMsg("部门不存在或已删除");
            }
            String sql = "(SELECT m.id,m.field_name AS fieldName,m.name,sa.show_status AS showStatus,sa.must_status AS mustStatus,0 AS `type` FROM saas_field_management m inner join \n"
                    + " saas_field_stauts_ref sa  on m.`id`=sa.`default_field_id` WHERE sa.org_id = ?)\n"
                    + " UNION ALL (SELECT fm.id,fm.field_name AS fieldName,fm.name,fm.show_status AS showStatus,fm.must_status AS mustStatus,1 AS `type` FROM saas_custom_field_management fm \n"
                    + "                   WHERE fm.org_id = ?)";
            List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql,
                    new Object[]{tokenRedisVo.getEnterpriseId(), tokenRedisVo.getEnterpriseId()});
            result.setResultData(maps);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 部门管理删除部门
     */
    public ResultBean<Object> deleteDepartment(String accessToken, Long depId) {
        LOG.info("---DepartmentService deleteDepartment accessToken={}", accessToken);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (depId == null) {
                result.setCode(StatusCode.ERROR_CODE_10004.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10004.getErrorMsg());
                return result;
            }

            Optional<Department> existDepartment = departmentRepository.findById(depId);
            if (existDepartment == null) {
                return ResultBean.failedResultWithMsg("部门不存在或已删除");
            }

            StringBuffer childDepIds = new StringBuffer();
            String sql = "SELECT id FROM ( SELECT t1.id,IF(FIND_IN_SET(parent_id, @pids) > 0,@pids := CONCAT(@pids, ',', id),0) AS ischild FROM ( SELECT id,parent_id FROM `saas_department` t ORDER BY parent_id, id ) t1,(SELECT @pids := ?) t2 ) t3 WHERE ischild != 0 \n";
            List<Long> ids = jdbcTemplate.queryForList(sql, new Object[]{depId}, Long.class);
            for (Long id : ids) {
                childDepIds.append(id).append(",");
            }
            childDepIds.append(depId);

            StringBuffer sbSql = new StringBuffer("SELECT COUNT(0) AS num FROM `saas_user_department_ref` r join saas_user u on r.user_id = u.id WHERE 1 = 1");
            if (!StringUtils.isBlank(childDepIds.toString())) {
                sbSql.append(" AND u.status != 2 AND r.`dep_id` IN (" + childDepIds.toString() + ")");
            }

            Map<String, Object> childPeople = jdbcTemplate.queryForMap(sbSql.toString());
            if (childPeople != null && childPeople.get("num") != null) {
                Long num = (Long) childPeople.get("num");
                if (num > 0) {
                    return ResultBean.failedResultWithMsg("部门或子部门下存在成员，不能删除");
                }
            }

            departmentRepository.deleteById(depId);
            departmentRepository.deleteByParentId(depId);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 部门管理删除部门--批量
     */
    public ResultBean<Object> batchDeleteDepartment(String accessToken, List<Long> depIds) {
        LOG.info("---DepartmentService batchDeleteDepartment accessToken={}", accessToken);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        for (Long depId : depIds) {
            try {
                if (tokenRedisVo == null) {
                    result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                    result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                    return result;
                }
                if (depId == null) {
                    result.setCode(StatusCode.ERROR_CODE_10004.getErrorCode());
                    result.setMsg(StatusCode.ERROR_CODE_10004.getErrorMsg());
                    return result;
                }
                Optional<Department> existDepartment = departmentRepository.findById(depId);
                if (existDepartment == null) {
                    return ResultBean.failedResultWithMsg("部门不存在或已删除");
                }

                StringBuffer childDepIds = new StringBuffer();
                String sql = "SELECT id FROM ( SELECT t1.id,IF(FIND_IN_SET(parent_id, @pids) > 0,@pids := CONCAT(@pids, ',', id),0) AS ischild FROM ( SELECT id,parent_id FROM `saas_department` t ORDER BY parent_id, id ) t1,(SELECT @pids := ?) t2 ) t3 WHERE ischild != 0 \n";
                List<Long> ids = jdbcTemplate.queryForList(sql, new Object[]{depId}, Long.class);
                for (Long id : ids) {
                    childDepIds.append(id).append(",");
                }
                childDepIds.append(depId);
                StringBuffer sbSql = new StringBuffer(
                        "SELECT COUNT(0) AS num FROM `saas_user_department_ref` WHERE 1=1 ");
                if (!StringUtils.isBlank(childDepIds.toString())) {
                    sbSql.append("  AND  `dep_id`  IN  (" + childDepIds.toString() + ")  ");
                }
                Map<String, Object> childPeople = jdbcTemplate.queryForMap(sbSql.toString());
                if (childPeople != null && childPeople.get("num") != null) {
                    Long num = (Long) childPeople.get("num");
                    if (num > 0) {
                        return ResultBean.failedResultWithMsg("子部门下存在部门成员不能删除");
                    }
                }
                departmentRepository.deleteById(depId);
                departmentRepository.deleteByParentId(depId);
            } catch (Exception e) {
                LOG.error(e.getMessage(), e);
                result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
                result.setMsg(e.getMessage());
            }
        }
        return result;
    }

    /*
     * 部门管理部门列表显示
     */
    public ResultBean<Object> departmentManagerList(String accessToken, Integer pageNumber, Integer pageSize,
                                                    Long parentId) {
        LOG.info("---DepartmentService departmentManagerList accessToken={},pageNumber={},pageSize={},parentId={}",
                accessToken, pageNumber, pageSize, parentId);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        ApiData<Map<String, Object>> apiData = new ApiData<>();
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }

            User existUser = userRepository.findById(tokenRedisVo.getId());
            if (existUser == null) {
                return ResultBean.failedResultWithMsg("用户信息不存在或已删除");
            }

            List<Long> allDepIds = new ArrayList<>();
            if (tokenRedisVo.getMasterStatus() == 1) {
                allDepIds.addAll(findHierarchyAll(tokenRedisVo.getEnterpriseId()));
            } else {
                List<UserDepartmentRef> userDepartmentRefList = userDepartmentRefRepository.findByUserId(existUser.getId());
                for (UserDepartmentRef userDepartmentRef : userDepartmentRefList) {
                    allDepIds.add(userDepartmentRef.getDepId());
                }
            }

            List<Department> department = departmentRepository.findByIdIn(allDepIds);
            if (department == null || department != null && department.size() <= 0) {
                return ResultBean.failedResultWithMsg("部门不存在或已删除");
            }

            // 所有权限部门及其子集部门id
            List<Long> depIds = new ArrayList<>();
            depIds.addAll(allDepIds);
            for (Long depId : allDepIds) {
                depIds.addAll(allChild(depId));
            }
            depIds = depIds.stream().distinct().collect(Collectors.toList());

            StringBuffer depIdStringBuffer = new StringBuffer();
            String depId = "";
            if (depIds != null && depIds.size() > 0) {
                for (Long id : depIds) {
                    depIdStringBuffer.append(id).append(",");
                }
                depId = depIdStringBuffer.substring(0, depIdStringBuffer.lastIndexOf(","));
            }

            StringBuffer sql = new StringBuffer(
                    "SELECT  DISTINCT d.`id`,d.`parent_id`,d.`name`,a1.name AS provinceName,a2.name AS cityName,a3.name AS districtName,a4.name AS streetName,a5.`name` AS communityName, d.max_num as maxNum "
                            + "FROM `saas_department` d \n"
                            + "LEFT JOIN `sys_area` a1 ON d.`province_id`=a1.id "
                            + "LEFT JOIN `sys_area` a2 ON d.`city_id`=a2.id "
                            + "LEFT JOIN `sys_area` a3 ON d.`district_id`=a3.id\n"
                            + "LEFT JOIN `sys_area` a4 ON d.`street_id`=a4.id \n"
                            + "LEFT JOIN `sys_area` a5 ON d.`community_id`=a5.id WHERE 1=1 ");
            if (parentId != null) {
                sql.append(" AND d.parent_id = ").append(parentId);
            }
            if (StringUtils.isNotBlank(depId)) {
                sql.append(" AND d.id IN (" + depId + ")  ");
            }


            // 查询总记录数
            String totalCount = "SELECT COUNT(0) FROM (" + sql + ") c ";
            Long total = jdbcTemplate.queryForObject(totalCount, Long.class);
            if (total == 0) {
                result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
                result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
                result.setResultData(null);
                return result;
            }

            List<Long> allChild = allChild(tokenRedisVo.getEnterpriseId());
            // 查询分页数据
            sql.append("  LIMIT  ").append(pageSize).append("  OFFSET ").append(pageNumber * pageSize);
            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql.toString());
            mapList.forEach(m -> {
                Long id = (Long) m.get("id");
                // Long num = 0L;
                // num = getNum(id,0L);
                // num = getChildAllData(id, num);
                // m.put("num",num);
                // 2023-3-4 zhiping 修复部门人数统计错误
                List<Map<String, Object>> currentDeptMembers = getCurrentDeptMembers(id);
                List<Map<String, Object>> childrenDeptMembers = getChildrenDeptMembers(id);
                // 根据用户id去除
                currentDeptMembers.addAll(childrenDeptMembers);
                List<Map<String, Object>> resultMap = currentDeptMembers.stream()
                        .filter(distinctByKeys(item -> item.get("id"), item -> item.get("id")))
                        .collect(Collectors.toList());
                m.put("num", resultMap.size());

                if (tokenRedisVo.getEnterpriseId().equals(id)) {
                    // currentCompany: 1 当前企业 ,0 不是当前企业
                    m.put("currentCompany", 1);
                } else {
                    m.put("currentCompany", 0);
                }

                // 如果是当前企业的下级部门,也设置为1
                for (Long child : allChild) {
                    if (child.equals(id)) {
                        m.put("currentCompany", 1);
                    }
                }
            });
            // Long parentNum =  mapList.stream().mapToLong(map ->(Long) map.get("num")).sum();
            // mapList.get(0).put("num",parentNum);

            apiData.setData(mapList);
            apiData.setTotal(total);
            result.setResultData(apiData);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }


    private <T> Predicate<T> distinctByKeys(Function<? super T, Object>... keyExtractors) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> {
            final List<?> keys = Arrays.stream(keyExtractors)
                    .map(ke -> ke.apply(t))
                    .collect(Collectors.toList());

            return seen.putIfAbsent(keys, Boolean.TRUE) == null;
        };
    }

    /**
     * 查询当前部门的成员
     *
     * @param deptId
     * @return
     */
    private List<Map<String, Object>> getCurrentDeptMembers(Long deptId) {
        String sql = "SELECT * FROM `saas_user_department_ref` d INNER JOIN `saas_user` u ON u.id=d.user_id WHERE u.status!=2  AND d.dep_id=? \n";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, new Object[]{deptId});
        return list;
    }

    /**
     * 查询子孙部门的成员
     *
     * @param deptId
     * @return
     */
    private List<Map<String, Object>> getChildrenDeptMembers(Long deptId) {
        List<Department> byParentId = departmentRepository.findByParentId(deptId);
        List<Map<String, Object>> members = new ArrayList<>();
        if (byParentId != null && byParentId.size() > 0) {
            for (Department dep : byParentId) {
                Long id = dep.getId();
                List<Map<String, Object>> currentDeptMembers = getCurrentDeptMembers(id);
                CollUtil.addAll(members, currentDeptMembers);
            }
        }
        return members;
    }


    /**
     * 递归获取子部门所有数据
     *
     * @param id
     * @param num
     * @return
     */
    private Long getChildAllData(Long id, Long num) {
        List<Department> byParentId = departmentRepository.findByParentId(id);

        if (byParentId != null && byParentId.size() > 0) {
            for (Department dep : byParentId) {
                num = getNum(dep.getId(), num);
                return getChildAllData(dep.getId(), num);
            }
        }
        return num;
    }

    /**
     * 查询当前id的人员总数
     *
     * @return
     */
    private Long getNum(Long id, Long count) {
        Long number = 0L;
        Optional<Department> departmentById = departmentRepository.findById(id);
        if (departmentById.isPresent()) {
            Department department = departmentById.get();
            Long departmentId = department.getId();
            String num = "SELECT COUNT(0) FROM `saas_user_department_ref` d INNER JOIN `saas_user` u ON u.id=d.user_id WHERE u.status!=2  AND d.dep_id=? \n";
            number = jdbcTemplate.queryForObject(num, new Object[]{departmentId}, Long.class);
        }
        return number + count;
    }

    /*
     * 部门管理限制人数
     */
    public ResultBean<Object> departmentLimitPeople(String accessToken, Long depId, Integer maxNum) {
        LOG.info("---DepartmentService departmentLimitPeople accessToken={},depId={},maxNum={}", accessToken, depId,
                maxNum);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (maxNum == null) {
                return ResultBean.failedResultWithMsg("限制人数不能为空");
            }
            Optional<Department> existDepartmentOptional = departmentRepository.findById(depId);
            if (existDepartmentOptional == null) {
                return ResultBean.failedResultWithMsg("部门不存在或已删除！");
            }
            Department existDepartment = existDepartmentOptional.get();
            Integer currMaxNum = existDepartment.getMaxNum() == null ? 0 : existDepartment.getMaxNum();
            // 获取上级部门的最大限制数，如果为空，提示先设置上级部门
            Optional<Department> parentDeptOptional = departmentRepository.findById(existDepartment.getParentId());
            if (parentDeptOptional.isPresent()) {
                Department department = parentDeptOptional.get();

                if (department.getMaxNum() == null) {
                    return ResultBean.failedResultWithMsg("请先设置上级部门限制数！");
                }

                if (maxNum > department.getMaxNum()) {
                    return ResultBean.failedResultWithMsg("子部门限制人数超出父级部门限制人数！");
                }

                // 获取父级部门下所有用户(一个菜单下的用户数，不能大于部门自己下的用户  + 下一级部门的限制数)
                String sbSql = "SELECT COUNT(0) AS num FROM saas_user_department_ref  WHERE dep_id = ?";
                Map<String, Object> childPeople = jdbcTemplate.queryForMap(sbSql, existDepartment.getParentId());
                Integer childUserNum = childPeople.get("num") == null ? 0 : Integer.parseInt(childPeople.get("num").toString());

                // 获取所有下级部门的限制数之和
                String childSql = "SELECT IFNULL(SUM(max_num),0) FROM saas_department d WHERE d.parent_id = ? ";
                Integer totalChildMaxNum = jdbcTemplate.queryForObject(childSql, Integer.class, existDepartment.getParentId());

                if (department.getMaxNum() < totalChildMaxNum + childUserNum + (maxNum - currMaxNum)) {
                    return ResultBean.failedResultWithMsg("子部门限制人数超出父级部门限制人数！");
                }
            }


            // 当前设置的部门，所有同级部门的限制人数之和不能大于上级部门设置限制，如果上级部门未设置，ji
            /*Integer currMaxNum = existDepartment.getMaxNum() == null?0:existDepartment.getMaxNum();
            if(maxNum > currMaxNum){
                Integer totalMaxNum = getAllChildDepartmentMaxNum(depId, currMaxNum, maxNum);
                if(totalMaxNum != null && totalMaxNum == -1){
                    return ResultBean.failedResultWithMsg("部门数据有误！");
                }

                // 当前当前设置部门
                if(totalMaxNum != null){
                    return ResultBean.failedResultWithMsg("子部门限制人数超出父级部门限制人数！");
                }
            }*/







            /*if(existDepartment.getParentId() != null && existDepartment.getParentId() != 0){
                Optional<Department> existParentDepartmentOptional = departmentRepository
                        .findById(existDepartment.getParentId());
                if (existParentDepartmentOptional == null) {
                    return ResultBean.failedResultWithMsg("父级部门不存在或已删除！");
                }
                Department parentDepartment = existParentDepartmentOptional.get();
                StringBuffer childDepIds = new StringBuffer();
                if (parentDepartment.getMaxNum() != null && parentDepartment.getMaxNum() != 0) {
                    String sql = "SELECT id,`name` FROM ( SELECT t1.id,t1.`name`,IF(FIND_IN_SET(parent_id, @pids) > 0,@pids := CONCAT(@pids, ',', id),0) AS ischild FROM ( SELECT id, parent_id,  `name` FROM `saas_department` t ORDER BY  parent_id,id ) t1,( SELECT @pids := ?) t2 ) t3 WHERE ischild != 0  \n";
                    List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, parentDepartment.getId());
                    maps.forEach(m -> {
                        childDepIds.append(m.get("id")).append(",");
                    });
                    childDepIds.append(parentDepartment.getId());
                    StringBuffer sbSql = new StringBuffer(
                            "SELECT COUNT(0) AS num FROM `saas_user_department_ref`  WHERE 1=1 ");
                    if (!StringUtils.isBlank(childDepIds.toString())) {
                        sbSql.append("  AND  `dep_id`  IN  (" + childDepIds.toString() + ")  ");
                    }
                    Map<String, Object> childPeople = jdbcTemplate.queryForMap(sbSql.toString());
                    if (childPeople != null && childPeople.get("num") != null) {
                        Long num = (Long) childPeople.get("num");
                        if (maxNum > parentDepartment.getMaxNum() - num) {
                            return ResultBean.failedResultWithMsg("子部门限制人数超出父级部门限制人数");
                        }
                    }
                }
            }*/

            existDepartment.setMaxNum(maxNum);
            departmentRepository.save(existDepartment);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /**
     * 获取符合验证条件的上级部门所有限制人数
     *
     * @param deptId
     * @return
     * @author shun
     * @date 2022年3月17日
     */
    public Integer getAllChildDepartmentMaxNum(Long deptId, Integer currDeptMaxNum, Integer newMaxNum) {
        // 获取当前设置部门的上级部门
        if (deptId == null) {
            return null;
        }
        Optional<Department> existDepartmentOptional = departmentRepository.findById(deptId);
        if (!existDepartmentOptional.isPresent()) {
            return -1;
        }
        Department department = existDepartmentOptional.get();
        if (department.getMaxNum() == null) {
            if (department.getParentId() != 0) {
                return getAllChildDepartmentMaxNum(department.getParentId(), currDeptMaxNum, newMaxNum);
            } else {
                // 如果是最高级别机构且maxnum为空，表示没有上级部门限制
                return null;
            }
        } else {
            // 获取所有下级部门
            String sql = "SELECT id,`name` FROM ( SELECT t1.id,t1.`name`,IF(FIND_IN_SET(parent_id, @pids) > 0,@pids := CONCAT(@pids, ',', id),0) AS ischild FROM ( SELECT id, parent_id,  `name` FROM `saas_department` t ORDER BY  parent_id,id ) t1,( SELECT @pids := ?) t2 ) t3 WHERE ischild != 0  \n";
            List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, department.getId());
            /*StringBuffer childDepIds = new StringBuffer();
            maps.forEach(m -> {
                childDepIds.append(m.get("id")).append(",");
            });*/

            List<Object> childDepIds = maps.stream().map(m -> m.get("id")).collect(Collectors.toList());

            // 获取该部门下所有下级部门的所有最大限制值
            String allSql = "SELECT sum(max_num) as totalMaxNum FROM saas_department d WHERE d.id IN " + SqlUtils.foreachIn(childDepIds.size()) + " group by d.id";
            Integer totalMaxNum = jdbcTemplate.queryForObject(allSql, Integer.class, childDepIds.toArray());

            totalMaxNum = totalMaxNum == null ? 0 : totalMaxNum;
            // 上级部门的最大值 > (当前所有下级一起的最大值 + 当前实际要增加的）
            if (department.getMaxNum() > totalMaxNum + (newMaxNum - currDeptMaxNum)) {
                return null;
            } else {
                return newMaxNum - currDeptMaxNum;
            }
        }
    }

    /*
     * 编辑部门
     */
    public ResultBean<Object> updateDepartmentInfo(String accessToken, DepartmentVO departmentVO) {
        LOG.info("---DepartmentService updateDepartmentInfo accessToken={},departmentVO={}", accessToken, departmentVO);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (departmentVO == null) {
                result.setCode(StatusCode.ERROR_CODE_10004.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10004.getErrorMsg());
                return result;
            }
            Long parentId = departmentVO.getParentId();
            String name = departmentVO.getName();
            Long depId = departmentVO.getId();
            if (depId == null) {
                return ResultBean.failedResultWithMsg("部门id不能为空");
            }
            if (StringUtils.isBlank(name)) {
                return ResultBean.failedResultWithMsg("部门名称不能为空");
            }
            Optional<Department> departmentDetail = departmentRepository.findById(depId);
            if (departmentDetail == null) {
                return ResultBean.failedResultWithMsg("部门信息不存在或已删除");
            }
            Department existDepartment = departmentRepository.findAllByParentIdAndName(departmentVO.getParentId(),
                    departmentVO.getName());
            if (existDepartment != null && existDepartment.getId() != departmentVO.getId()) {
                return ResultBean.failedResultWithMsg("名称已被使用");
            }
            Optional<Department> parentDepartmentOptional = departmentRepository.findById(parentId);
            if (parentDepartmentOptional == null) {
                return ResultBean.failedResultWithMsg("上级部门信息不存在或已删除");
            }
            Department department = departmentDetail.get();
            // String childCode = department.getCode();
            department.setName(name);
            department.setParentId(parentId);
            // String newCode = buildCode(parentId, tokenRedisVo.getEnterpriseId());
            // department.setCode(newCode);
            Department save = departmentRepository.save(department);
            /*if (save != null) {
                List<Long> idsList = allChild(depId);
                List<Department> allDepartment = departmentRepository.findByIdIn(idsList);
                for (Department childDepartment : allDepartment) {
                    StringBuffer buffer = new StringBuffer(childDepartment.getCode());
                    buffer.replace(0, childCode.length(), save.getCode());
                    childDepartment.setCode(String.valueOf(buffer));
                    departmentRepository.save(childDepartment);
                }
            } else {
                result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10001.getErrorMsg());
            }*/
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 导出部门成员信息
     */
    public void departmentPeopleExport(String accessToken, Long depId) {
        LOG.info("---DepartmentService updateDepartmentInfo accessToken={},depId={}", accessToken, depId);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return;
            }
            Optional<Department> companyOptional = departmentRepository.findById(tokenRedisVo.getEnterpriseId());
            if (companyOptional == null) {
                return;
            }
            Optional<Department> existDepartment = departmentRepository.findById(depId);
            if (existDepartment == null) {
                return;
            }
            Department company = companyOptional.get();
            Department department = existDepartment.get();
            // List<User> list = new ArrayList<>();
            // List<UserDepartmentRef> userDepartmentRefList = userDepartmentRefRepository.findByDepId(department.getId());
            // for (UserDepartmentRef userDepartmentRef : userDepartmentRefList) {
            //     User user = userRepository.findById(userDepartmentRef.getUserId());
            //     if (user != null) {
            //         list.add(user);
            //     }
            // }

            List<Long> idsList = allChild(depId);
            idsList.add(depId);
            String depIdSql = "SELECT `user_id` FROM `saas_user_department_ref` WHERE 1=1 ";
            StringBuffer depIds = new StringBuffer();
            for (Long id : idsList) {
                depIds.append(id).append(",");
            }
            String depIdSubstring = depIds.substring(0, depIds.lastIndexOf(","));
            if (depId != null) {
                depIdSql += "  AND `dep_id` IN (" + depIdSubstring + ")";
            }
            List<String> userIdsList = jdbcTemplate.queryForList(depIdSql, String.class);
            StringBuffer userIds = new StringBuffer();
            for (String s : userIdsList) {
                userIds.append("'").append(s).append("'").append(",");
            }
            String userId = StringUtils.isNotBlank(userIds) ? userIds.substring(0, userIds.lastIndexOf(",")) : null;
            String columns = "SELECT id,`name`,`mobile`,`email`,`wrong_number`,`status`,`type`,`is_user_id`,`position`,`entry_time`,`remarks`,`job_number`,`create_time`,`leave_date`,`operator_id` FROM `saas_user` WHERE `status` != 2 \n";
            columns += "  AND `id` IN (" + userId + ")";
            List<Object> args = new ArrayList<>();
            List<User> data = jdbcTemplate.query(columns, new BeanPropertyRowMapper<>(User.class), args.toArray());
            try {
                HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                        .getResponse();
                response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

                // ckValStr = "1_2_3_4";
                Workbook workbook = getDeviceExcel(data, department, company);

                // 导出文件下载
                DownloadUtil downloadUtil = new DownloadUtil();
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                workbook.write(bos);
                // 文件名
                String fileName = URLEncoder.encode(company.getName() + "-通讯录模板.xls", "utf-8");
                downloadUtil.download(bos, response, fileName);
                // 关闭
                workbook.close();

            } catch (Exception e) {
                LOG.error(e.getMessage(), e);
                e.printStackTrace();
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
    }

    private Workbook getDeviceExcel(List<User> datas, Department department, Department company) {
        Workbook workbook = new SXSSFWorkbook(100);
        String sheetName = "sheet1";
        Sheet sheet1 = workbook.createSheet(sheetName);
        if (datas != null && datas.size() > 0) {
            Row title1 = sheet1.createRow(0); // 创建第一行标题
            Cell cell = title1.createCell(0);
            sheet1.setColumnWidth(0, 50 * 256);
            cell.setCellValue("部门人员信息表");
            title1 = sheet1.createRow(1);
            cell = title1.createCell(0);
            sheet1.setColumnWidth(0, 25 * 256);
            cell.setCellValue("ID号");
            cell = title1.createCell(1);
            sheet1.setColumnWidth(1, 25 * 256);
            cell.setCellValue("姓名");
            cell = title1.createCell(2);
            sheet1.setColumnWidth(2, 25 * 256);
            cell.setCellValue("手机号码");
            cell = title1.createCell(3);
            sheet1.setColumnWidth(3, 25 * 256);
            cell.setCellValue("部门");
            cell = title1.createCell(4);
            sheet1.setColumnWidth(4, 25 * 256);
            cell.setCellValue("职位");
            cell = title1.createCell(5);
            sheet1.setColumnWidth(5, 25 * 256);
            cell.setCellValue("邮箱");
            cell = title1.createCell(6);
            sheet1.setColumnWidth(6, 25 * 256);
            cell.setCellValue("角色");
            cell = title1.createCell(7);
            sheet1.setColumnWidth(7, 25 * 256);
            cell.setCellValue("入职时间");
            List<CustomFieldManagement> customFieldManagementList = customFieldManagementRepository
                    .findByOrgId(company.getId());
            int cellIndex = 8;
            for (int i = 0; i < customFieldManagementList.size(); i++) {
                cell = title1.createCell(cellIndex);
                sheet1.setColumnWidth(cellIndex, 25 * 256);
                cell.setCellValue(customFieldManagementList.get(i).getName());
                cellIndex++;
            }
            int dataRowIndex = 2;// 当前行
            for (User user : datas) {
                Row createRow = sheet1.createRow(dataRowIndex);
                cell = createRow.createCell(0);
                cell.setCellValue(user.getId());
                cell = createRow.createCell(1);
                cell.setCellValue(user.getName());
                cell = createRow.createCell(2);
                cell.setCellValue(user.getMobile());
                cell = createRow.createCell(3);
                String deptNames = "";
                List<UserDepartmentRef> userDepartmentRefList = userDepartmentRefRepository.findByUserId(user.getId());
                for (UserDepartmentRef userDepartmentRef : userDepartmentRefList) {
                    Optional<Department> existDepartment = departmentRepository.findById(userDepartmentRef.getDepId());
                    if (existDepartment != null) {
                        deptNames += existDepartment.get().getName() + ",";
                    }
                }
                if (StringUtils.isNotBlank(deptNames)) {
                    deptNames = deptNames.substring(0, deptNames.lastIndexOf(","));
                }
                cell.setCellValue(deptNames);
                cell = createRow.createCell(4);
                cell.setCellValue(user.getPosition());
                String email = user.getEmail();
                if (StrUtil.isNotBlank(email)) {
                    cell = createRow.createCell(5);
                    cell.setCellValue(user.getEmail());
                }
                List<UserRoleRef> userRoleRefs = userRoleRefRepository.findByUserId(user.getId());
                String roles = "";
                for (UserRoleRef userRoleRef : userRoleRefs) {
                    Role role = roleRepository.findByIdAndProperty(userRoleRef.getRoleId(), 2);
                    if (role != null) {
                        roles += role.getName() + ",";
                    }
                }
                if (StringUtils.isNotBlank(roles)) {
                    roles = roles.substring(0, roles.lastIndexOf(","));
                }
                cell = createRow.createCell(6);
                cell.setCellValue(roles);
                cell = createRow.createCell(7);
                Date entryTime = user.getEntryTime();
                String strEntryTime = DateUtil.formatDateTime(entryTime);
                cell.setCellValue(strEntryTime);
                cellIndex = 8;
                for (int i = 0; i < customFieldManagementList.size(); i++) {
                    cell = createRow.createCell(cellIndex);
                    List<CustomFieldValue> userCustomFieldValue = customFieldValueRepository.findByUserId(user.getId());
                    for (CustomFieldValue customFieldValue : userCustomFieldValue) {
                        if (customFieldManagementList.get(i).getId() == customFieldValue.getFieldId()) {
                            cell.setCellValue(customFieldValue.getFieldValue());
                        }
                    }
                    cellIndex++;
                }
                dataRowIndex++;
            }
        } else {
            Row noData = workbook.getSheet(sheetName).createRow(0);
            Cell cell = noData.createCell(0);
            cell.setCellValue("无查询数据");
        }
        return workbook;
    }

    /*
     * 查询层级架构下级orgId(包含当前orgId)
     */
    public List<DepartmentParentVO> findHierarchyParentAll(Long orgId) {
        DepartmentParentVO vo = new DepartmentParentVO();
        DepartmentHierarchy departmentHierarchy = departmentHierarchyRepository.findByOrgId(orgId);
        String sql = " SELECT id, org_id as orgId, parent_id AS parentId FROM ( SELECT t1.parent_id,t1.id,t1.org_id,IF(FIND_IN_SET(parent_id, @pids) > 0,@pids := CONCAT(@pids, ',', id),0) AS ischild FROM ( SELECT id,org_id,parent_id FROM `saas_department_hierarchy` t ORDER BY parent_id, id ) t1,(SELECT @pids := ?) t2 ) t3 WHERE ischild != 0 ";
        // orgIds.addAll(jdbcTemplate.queryForList(sql, new Object[] {
        // departmentHierarchy.getId() }, Long.class));

        List<DepartmentParentVO> dpList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(DepartmentParentVO.class),
                departmentHierarchy.getId());
        vo.setOrgId(orgId);
        vo.setId(departmentHierarchy.getId());
        dpList.add(vo);

        for (DepartmentParentVO dParentVO : dpList) {
            for (DepartmentParentVO dVo : dpList) {
                if (dParentVO.getParentId() != null && dParentVO.getParentId().longValue() == dVo.getId().longValue()) {
                    dParentVO.setParentId(dVo.getOrgId());
                    break;
                }
            }
        }
        return dpList;
    }
}
